package file;

import operator.Handler;
import pri.file.FOperator;
import pri.util.Sys;
import common.Constant;
import common.Singleton;
import view.Main;
import vo.Mean;

import javax.swing.*;
import javax.swing.filechooser.FileFilter;
import java.io.File;
import java.io.IOException;
import java.util.Iterator;
import java.util.TreeSet;

public class FUtil {

    private Handler handler;

    private static FUtil futil;

    private FUtil() {}

    public static FUtil getUtil() {
        if (futil == null) {
            futil = new FUtil();
            futil.handler = Singleton.handler();
        }
        return futil;
    }

    /**
     * 同时输出XDoc和XML文件
     */
    public void writeAll() {
        if (handler.saved())
            return;

        boolean ask = Constant.usingXDoc == null;
        String path = getSavePath(" xDoc 和 xml ", ask);
        Singleton.xmlOperator().writeXML(findOutPutFile("xml", path));
        Singleton.xDocOperator().writeXDOC(findOutPutFile("xDoc", path));
        Singleton.handler().modifySaved();
    }

    private String getSavePath(String fileKind, boolean ask) {
        File file = getActiveFile();
        String path = null;
        if (!ask || JOptionPane.showConfirmDialog(Main.main, "保存" + fileKind + "到源文件所在目录？", "选择保存位置",
                JOptionPane.YES_NO_OPTION) == 0) {
            path = file.getParent() + "/";
        } else {
            JFileChooser jfc = new JFileChooser();
            jfc.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
            jfc.setDialogTitle("请选择保存位置");
            jfc.showOpenDialog(Main.main);
            File selected = jfc.getSelectedFile();
            if (selected != null)
                path = selected.getPath() + "/";
        }

        return path;
    }

    /**
     * 获取输出文件
     */
    private File findOutPutFile(String kind, String path) {
        if (path == null)
            return null;

        File file = getActiveFile();

        String fileName = file.getName();
        StringBuilder name = new StringBuilder();
        for (int i = 0; i < fileName.length(); i++) {
            if (fileName.charAt(i) == '.')
                break;
            name.append(fileName.charAt(i));
        }
        return new File(path + name + "." + kind);
    }

    private File getActiveFile(){
        File file = Constant.usingXDoc;
        if(file == null)
            file = Constant.usingDoc;
        return file;
    }

    File getOutPutFile(String fileKind, boolean ask) {
        return findOutPutFile(fileKind, getSavePath(fileKind, ask));
    }

    /**
     * 获取指定的文件
     *
     * @param kind 后缀
     */
    File findFile(String... kind) {
        JFileChooser jfc = new JFileChooser();
        // 清除所有文件选项
        jfc.removeChoosableFileFilter(jfc.getFileFilter());
        jfc.addChoosableFileFilter(new FileFilter() {
            public String getDescription() {
                StringBuilder des = new StringBuilder();
                for (int i = 0; i < kind.length; i++) {
                    des.append(kind[i]);
                    if (i + 1 < kind.length)
                        des.append("、");
                }
                return des + "文件";
            }

            public boolean accept(File f) {
                if (f.isDirectory())
                    return true;
                for (String aKind : kind) {
                    if (f.getName().endsWith(aKind))
                        return true;
                }
                return false;
            }
        });
        jfc.setDialogTitle("请选择文件");
        jfc.setDialogType(JFileChooser.SAVE_DIALOG);// Mac可能不支持Open_Dialog
        if (jfc.showDialog(null, "选择/打开") == 1)
            return null;
        return jfc.getSelectedFile();
    }

    /**
     * 对所有意象进行排序
     */
    void setMeanTree() {
        TreeSet<Mean> mean_tree = new TreeSet<>((m1, m2) -> m1.getTop() > m2.getTop() ? 1 : -1);

        mean_tree.addAll(handler.allMean);
        Iterator<Mean> im = mean_tree.iterator();
        int index = 1;
        while (im.hasNext()) {
            Mean next = im.next();
            next.index_in_full_text = index++;
        }
    }

    /**
     * 获取配置文件路径 Windows下为D盘CTCRE文件夹. Mac下为用户文件夹下CTCRE文件夹<br/>
     * Window分隔符为 \ ，Mac 为 /<br/>
     * 获取分隔符用{@code File.separator}
     */
    String getConfigPath() {
        String os = Sys.getInfo(Sys.Os);
        if (os.startsWith("Windows"))
            return "D:/" + Constant.EN_NAME;
        else if (os.startsWith("Mac") || os.startsWith("OS")) {
            File file = new File("a.txt");// 不以盘符起始的路径都是相对路径
            String parts[] = file.getAbsolutePath().replace("/", "~").split("~");
            StringBuilder path = new StringBuilder();
            for (int i = 1; i < 3; i++) {// Mac系统路径首位是 separator ，分割后从第二位开始
                path.append("/").append(parts[i]);
            }
            path.append("/" + Constant.EN_NAME);
            return path.toString();
        } else {
            if (JOptionPane.showOptionDialog(null, "软件暂不支持" + os + "系统", "抱歉", JOptionPane.DEFAULT_OPTION,
                    JOptionPane.WARNING_MESSAGE, null, null, null) == 0)
                System.exit(-1);
        }
        return "";
    }

    /**
     * 写源文件到TXT
     */
    void writeSourceText() {
        File out = findOutPutFile("txt", getSavePath("txt", false));
        try {
            out.createNewFile();
        } catch (IOException e) {
            e.printStackTrace();
        }
        FOperator.write(out, Singleton.handler().getContext(), Constant.Encode);
    }

}